/* eslint-disable */
function getLenthAfterPoint(v: number): number {
  let _v
  try {
    _v = v.toString().split('.')[1].length
  } catch (f) {
    _v = 0
  }
  return _v
}

export function add(a: number, b: number): number {
  const c = getLenthAfterPoint(a)
  const d = getLenthAfterPoint(b)
  const e = Math.pow(10, Math.max(c, d))
  return (mul(a, e) + mul(b, e)) / e
}

export function sub(a: number, b: number): number {
  const c = getLenthAfterPoint(a)
  const d = getLenthAfterPoint(b)
  const e = Math.pow(10, Math.max(c, d))
  return (mul(a, e) - mul(b, e)) / e
}

export function mul(a: number, b: number): number {
  let c = 0
  const d = a.toString()
  const e = b.toString()
  c += getLenthAfterPoint(a)
  c += getLenthAfterPoint(b)
  return (
    (Number(d.replace('.', '')) * Number(e.replace('.', ''))) / Math.pow(10, c)
  )
}

export function div(a: number, b: number): number {
  const e = getLenthAfterPoint(a)
  const f = getLenthAfterPoint(b)
  const c = a.toString().replace('.', '')
  const d = b.toString().replace('.', '')
  if (c.length > 10 || d.length > 10) {
    const max = Math.pow(10, 14)
    return Math.round((a / b) * max) / max
  }
  return mul(Number(c) / Number(d), Math.pow(10, f - e))
}

export function mol(a: number, b: number): number {
  const c = getLenthAfterPoint(a)
  const d = getLenthAfterPoint(b)
  const e = Math.pow(10, Math.max(c, d))
  return (mul(a, e) % mul(b, e)) / e
}

export function between(val: number, min: number, max: number): number {
  return Math.min(Math.max(val, min), max)
}

export function getUrl(url: string, para: any, ifNotEnc: boolean): string {
  if (para) {
    let q = ''
    if (url.indexOf('?') >= 0) {
      q = '&'
    } else {
      q = '?'
    }

    for (const k in para) {
      if (typeof para[k] === 'undefined') {
        continue
      }
      if (q.length > 1) {
        q += '&'
      }
      if (ifNotEnc) {
        q = q + k + '=' + para[k]
      } else {
        q = q + k + '=' + encodeURIComponent(para[k])
      }
    }

    url = url + q
  }
  return url
}

export function catIn(target: Node | null, parent: Node | null): boolean {
  const path = []
  let parentNode = target
  while (parentNode && parentNode !== document.body) {
    path.push(parentNode)
    parentNode = parentNode.parentNode
  }
  return !!parent && path.indexOf(parent) !== -1
}

export function checkFileType(src: string, type: string): boolean {
  if (!src) {
    return false
  }
  const index = src.lastIndexOf('?')
  return !!src && src.substring(0, index === -1 ? void 0 : index).endsWith(type)
}

export function cloneObject<T>(obj: T, deep = true): T {
  return deep ? JSON.parse(JSON.stringify(obj)) : Object.assign({}, obj)
}
export function diffObject(oldObj: any, newObj: any): any {
  const diff: any = {}
  let flag = false
  for (const key in newObj) {
    if (typeof newObj[key] === 'object') {
      if (typeof oldObj[key] === 'object') {
        const ret = diffObject(oldObj[key], newObj[key])
        if (ret) {
          flag = true
          diff[key] = ret
        }
      } else {
        diff[key] = newObj[key]
      }
    } else {
      if (newObj[key] !== oldObj[key]) {
        flag = true
        diff[key] = newObj[key]
      }
    }
  }
  return flag ? diff : null
}

export function equals(a: any, b: any): boolean {
  if (typeof a !== 'object') {
    return a === b
  } else if (Object.keys(a).length !== Object.keys(b).length) {
    return false
  } else {
    const flag = true
    for (const key in a) {
      if (a[key] !== b[key]) {
        return false
      }
    }
    return flag
  }
}
export function secToTime(sec = 0, dayMode = false): string {
  if (sec < 0) {
    return secToTime(sec + 86400, dayMode)
  }
  let h = Math.floor(sec / 3600)
  if (dayMode) {
    h = h % 24
  }
  const m = Math.floor((sec % 3600) / 60)
  const s = Math.floor(sec % 60)
  const f = Math.floor((sec % 1) * 30)
  return `${fixZero(h)}:${fixZero(m)}:${fixZero(s)}:${fixZero(f)}`
}

export function formatTime(sec = 0): string {
  if (sec < 0) {
    return secToTime(sec + 86400, false)
  }
  const h = Math.floor(sec / 3600)
  const m = Math.floor((sec % 3600) / 60)
  const s = Math.floor(sec % 60)
  return `${fixZero(h)}:${fixZero(m)}:${fixZero(s)}`
}

export function timeToSec(start: number | Date, end: number | Date): number {
  return (+new Date(end) - +new Date(start)) / 1000 || 0
}

export function getFramesBySecs(secs: number): number {
  const h = Math.floor(secs / 3600)
  const m = Math.floor((secs % 3600) / 60)
  const s = Math.floor(secs % 60)
  const f = Math.floor(mol(secs, 1))
  return (
    ((h << (24 + m)) << 16) &
    ((0x00ff0000 + s) << 8) &
    (0x0000ff00 + f) &
    0x000000ff
  )
}

export function fixZero(num: number): string {
  if (num < 10) {
    return '0' + num
  }
  return num + ''
}

export function throttle(
  delay: number,
  action: Function,
  immediately: boolean
): Function {
  let last = 0
  let id = -1
  return function (this: any, ...args: any[]) {
    if (last === 0 && immediately) {
      action.apply(this, args)
      last = +new Date()
      return
    }
    clearTimeout(id)
    const curr = +new Date()
    if (curr - last > delay) {
      action.apply(this, args)
      last = curr
    } else {
      id = setTimeout(() => action.apply(this, args), delay)
      return id
    }
  }
}

const throttleMap: any = {}
export function throttleByTag(
  delay: number,
  action: Function,
  immediately: boolean,
  tag = 'default'
): Function {
  return (
    throttleMap[tag] ||
    ((throttleMap[tag] = throttle(delay, action, immediately)),
    throttleMap[tag])
  )
}

export function formatDate(date: Date, format: string): string {
  const o: any = {
    'M+': date.getMonth() + 1, // month
    'd+': date.getDate(), // day
    'h+': date.getHours(), // hour
    'm+': date.getMinutes(), // minute
    's+': date.getSeconds(), // second
    'q+': Math.floor((date.getMonth() + 3) / 3), // quarter
    S: date.getMilliseconds(), // millisecond
  }
  if (/(y+)/.test(format)) {
    format = format.replace(
      RegExp.$1,
      (date.getFullYear() + '').substr(4 - RegExp.$1.length)
    )
  }
  for (const k in o) {
    if (new RegExp('(' + k + ')').test(format)) {
      format = format.replace(
        RegExp.$1,
        RegExp.$1.length === 1 ? o[k] : ('00' + o[k]).substr(('' + o[k]).length)
      )
    }
  }
  return format
}

export function move<T>(arr: Array<T>, from: number, to: number) {
  const index = from > to ? from + 1 : from
  arr.splice(to, 0, arr[from])
  arr.splice(index, 1)
}
